﻿using System;
using IceDog.DNF.Program.Poker.Core.PokerEventHandler;
using IceDog.DNF.Program.Poker.Core.PokerException;

namespace IceDog.DNF.Program.Poker.Core
{
    /// <summary>
    /// 表示牌堆的对象
    /// </summary>
    public class Deck:ICloneable
    {
        private readonly CardList _cardList;

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public Deck()
        {
            _cardList = new CardList();
            for (int i = 1; i <= 4; i++)
            {
                for (int j = 1; j <= 13; j++)
                {
                    _cardList.Add(new Card((Suit)i, (Rank)j));
                }
            }
        }
        /// <summary>
        /// 自定义构造函数
        /// </summary>
        /// <param name="isAceHigh">判断A点是比K大还是比2小，如果是true，则是最大的牌，否则是最小的牌</param>
        public Deck(bool isAceHigh):this()
        {
            Card.IsAceHigh = isAceHigh;
        }
        /// <summary>
        /// 自定义构造函数
        /// </summary>
        /// <param name="useTrump">使用王牌花色(即在花色不同的情况下，此花色比其他的花色大，牌面符号大小无用)</param>
        /// <param name="trump">设置王牌花色(即在花色不同的情况下，此花色比其他的花色大，牌面符号大小无用)</param>
        public Deck(bool useTrump, Suit trump):this()
        {
            Card.UseTrump = useTrump;
            Card.Trump = trump;
        }

        /// <summary>
        /// 自定义构造函数
        /// </summary>
        /// <param name="isAceHigh">判断A点是比K大还是比2小，如果是true，则是最大的牌，否则是最小的牌</param>
        /// <param name="useTrump">使用王牌花色(即在花色不同的情况下，此花色比其他的花色大，牌面符号大小无用)</param>
        /// <param name="trump">设置王牌花色(即在花色不同的情况下，此花色比其他的花色大，牌面符号大小无用)</param>
        public Deck(bool isAceHigh, bool useTrump, Suit trump) :this()
        {
            Card.IsAceHigh = isAceHigh;
            Card.UseTrump = useTrump;
            Card.Trump = trump;
        }
        /// <summary>
        /// 私有构造函数，用于克隆牌堆
        /// </summary>
        /// <param name="list"></param>
        private Deck(CardList list)
        {
            _cardList = list;
        }

        /// <summary>
        /// 洗牌操作
        /// </summary>
        public void Shuffle()
        {
            var flag = new bool[52];
            var newDeck = new CardList();
            var ran = new Random();
            for (int i = 0; i < 52; i++)
            {
                var index = 0;
                var foundCard = false;
                while (!foundCard)
                {
                    index = ran.Next(52);
                    if (!flag[index])
                    {
                        foundCard = true;
                    }
                }
                flag[index] = true;
                newDeck.Add(_cardList[index]);
            }
            newDeck.CopyTo(_cardList);
        }
        /// <summary>
        /// 获取卡片
        /// </summary>
        /// <param name="num">值只能在1到52之间(包括1和52)</param>
        /// <returns></returns>
        public Card GetCard(int num)
        {
            if (num>0&&num<53)
            {
                var card = _cardList[num - 1];
                
                if (num.Equals(52))
                {   //通知获取最后一张牌的事件
                    LastCardDrawn?.Invoke(this,new LastCardDrawnEventHandler(card));
                }
                return card;
            }
            throw new CardOutOfRangeException(_cardList.Clone() as CardList);
        }

        /// <summary>
        /// 复制牌堆
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return new Deck(_cardList.Clone() as CardList);
        }
        /// <summary>
        /// 获取最后一张牌的事件
        /// </summary>
        public event EventHandler<LastCardDrawnEventHandler> LastCardDrawn;
    }
}
